package ptij.ADSL.common;

import ptolemy.kernel.*;
import ptolemy.kernel.util.*;
import ptolemy.data.*;
import ptolemy.data.type.*;
import ptolemy.actor.*;
import ptolemy.domains.de.kernel.*;

//////////////////////////////////////////////////////////////////////////
//// Timer
/**

@author Ivan Jeukens
*/
public class Timer extends DEActor {        

    public Timer(CompositeEntity container, String name) throws
            NameDuplicationException, IllegalActionException {
        super(container, name);

	startTimer = new TypedIOPort(this, "startTimer", true, false);
	startTimer.setTypeEquals(BaseType.DOUBLE);

	stopTimer = new TypedIOPort(this, "stopTimer", true, false);
	stopTimer.setTypeEquals(BaseType.GENERAL);

	timerEvent = new TypedIOPort(this, "timerEvent", false, true);
	timerEvent.setTypeEquals(BaseType.GENERAL);
    }

    ///////////////////////////////////////////////////////////////////
    ////                     ports and parameters                  ////
    
    public TypedIOPort startTimer;
    public TypedIOPort stopTimer;    
    public TypedIOPort timerEvent;    
    
    ///////////////////////////////////////////////////////////////////
    ////                         public methods                    ////
    
    public void fire() throws IllegalActionException {
        if(stopTimer.hasToken(0)) {
            if(_active == 0) {
	        throw new IllegalActionException(this, "Trying to stop when " +
		    "it was not started");
	    }
	    stopTimer.get(0);
	    _active = 0;
	}
	
	if(startTimer.hasToken(0)) {
            if(_active != 0) {
	        throw new IllegalActionException(this, "Trying to start when " +
		    "it was not stoped");
	    }
	    DoubleToken dt = (DoubleToken) startTimer.get(0);
            double t = dt.doubleValue() + 
	        ((DEDirector)getDirector()).getCurrentTime();
	    ((DEDirector)getDirector()).fireAt(this, t);
	    _active = t;
	}
	
	if(((DEDirector)getDirector()).getCurrentTime() == _active) {
	    _active = 0;
	    timerEvent.send(0, new Token());
	}
	
    }
    
    ///////////////////////////////////////////////////////////////////
    ////                         private variables                 ////
    
    private double _active;
}
